#include "upper_communication_coder.h"
#include <stdlib.h>
#include <string.h>

#define DECODER_STATIC_BUF_MIN_SIZE     (128)
#define DECODER_BUF_SIZE                (512)

#if 1
    #include "elog.h"
    #define TAG "coder"
    #define CODER_LOGD(tag,...) elog_d(tag,__VA_ARGS__)
    #define CODER_LOGI(tag,...) elog_i(tag,__VA_ARGS__)
    #define CODER_LOGW(tag,...) elog_w(tag,__VA_ARGS__)
    #define CODER_LOGE(tag,...) elog_e(tag,__VA_ARGS__)
#else
    #define CODER_LOGD(tag,...)
    #define CODER_LOGI(tag,...)
    #define CODER_LOGW(tag,...)
    #define CODER_LOGE(tag,...)
#endif

static nano_coder_handle_t coder_static_create(uint8_t* buf,uint16_t len);
static nano_coder_handle_t coder_create(void);
static uint8_t coder_delete(nano_coder_handle_t handle);
static nano_unpack_status_t* coder_unpack(nano_coder_handle_t handle,nano_pack_t** pack,uint8_t* bytes,uint16_t len);
static uint16_t coder_empack(nano_coder_handle_t handle,uint8_t* bytes_buff,uint16_t buf_len);
static void coder_reset(nano_coder_handle_t handle);

typedef struct{
    uint8_t status;
    uint8_t is_static:1;
    uint8_t* deooder_buf;
    uint16_t decoder_buf_len;
    uint16_t decoder_buf_index;
}coder_ctx_t;

static nano_coder_handle_t coder_static_create(uint8_t* buf,uint16_t len)
{
    coder_ctx_t* ctx = (coder_ctx_t*)buf;
    nano_coder_handle_t handle = (coder_ctx_t*)ctx;

    if( len < sizeof (coder_ctx_t) + DECODER_STATIC_BUF_MIN_SIZE )
    {
        CODER_LOGE(TAG,"don`t have enough static buf to create coder.static buf size:%d , min need buf size:%d" , len , sizeof (coder_ctx_t) + DECODER_STATIC_BUF_MIN_SIZE );
        return NULL;
    }

    ctx->is_static = 1;
    coder_reset(handle);

    CODER_LOGI(TAG,"static coder init.");

    return NULL;
}

static nano_coder_handle_t coder_create(void)
{
    coder_ctx_t* ctx = (coder_ctx_t*)malloc(sizeof(coder_ctx_t));
    nano_coder_handle_t handle = (coder_ctx_t*)ctx;

    ctx->is_static = 0;
    coder_reset(handle);

    return handle;
}

static uint8_t coder_delete(nano_coder_handle_t handle)
{
    coder_ctx_t* ctx = (coder_ctx_t*)handle;

    if( !ctx->is_static )
    {
        free(ctx->deooder_buf);
        free(ctx);
    }

    return 0;
}

static nano_unpack_status_t* coder_unpack(nano_coder_handle_t handle,nano_pack_t** pack,uint8_t* bytes,uint16_t len)
{
    coder_ctx_t* ctx = (coder_ctx_t*)handle;

    *pack = NULL;
}

static uint16_t coder_empack(nano_coder_handle_t handle,uint8_t* bytes_buff,uint16_t buf_len)
{
    coder_ctx_t* ctx = (coder_ctx_t*)handle;


}

static void coder_reset(nano_coder_handle_t handle)
{
    coder_ctx_t* ctx = (coder_ctx_t*)handle;

    uint8_t* buff = ctx->deooder_buf;
    uint16_t buff_len = ctx->decoder_buf_len;

    if( ctx->is_static )
    {
        memset(ctx,0,sizeof(coder_ctx_t));
        ctx->is_static = 1;
    }
    else
    {
        memset(ctx,0,sizeof(coder_ctx_t));
    }

    ctx->deooder_buf = buff;
    ctx->decoder_buf_len = buff_len;
}

void get_upper_communication_decoder_opt(nano_decoder_opt_t* opt)
{
    opt->coder_create = coder_create;
    opt->coder_delete = coder_delete;
    opt->coder_empack = coder_empack;
    opt->coder_reset = coder_reset;
    opt->coder_static_create = coder_static_create;
    opt->coder_unpack = coder_unpack;
}
